/**
 * 
 */
package com.geekteam.geometrychess.database;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import com.geekteam.geometrychess.room.entity.Player;
import com.geekteam.geometrychess.utils.Code;

/**
 * @author MtRol
 * 
 */
public class DataAccessor {

	private static final String USER_NAME = "root";
	private static final String PASSWORD = "";
	private static final String URL = "jdbc:mysql://127.0.0.1:3306/geometrychess";

	private static DataAccessor mData;
	private Connection mConnect;
	private Statement mStatement;

	public static DataAccessor getInstance() {
		if (mData == null) {
			synchronized (DataAccessor.class) {
				if (mData == null) {
					mData = new DataAccessor();
				}
			}
		}

		return mData;
	}

	private DataAccessor() {
		try {
			mConnect = DriverManager.getConnection(URL, USER_NAME, PASSWORD);
			mStatement = mConnect.createStatement();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/***
	 * 
	 * @param userName
	 *            name for check
	 * @param password
	 *            pass of user
	 * @return code for check. that define in {@link MessageCode}
	 */
	public int checkLogin(String userName, String password) {
		// check user and pass before access database
		if (userName.equals("")) {
			return Code.USER_NULL;
		}
		if (password.equals("")) {
			return Code.PASS_NULL;
		}

		// access to database get information of user
		String sql = "select user,password from user where user ='" + userName
				+ "';";
		checkDataAccess();
		try {
			mStatement.executeQuery(sql);
			ResultSet set = mStatement.getResultSet();

			if (!set.next()) {
				System.out.println("user not found!!");
				return Code.USER_NOT_FOUND;
			} else if (!set.getString("password").equals(password)) {
				System.out.println("password is wrong");
				return Code.INVALID_PASSWORD;
			}

			mStatement.close();
			mConnect.close();
		} catch (SQLException e) {
			e.printStackTrace();
			return Code.UNKNOWN_ERROR;
		}
		return Code.SUCCESS;
	}

	/**
	 * get data of player has name @param userName
	 * 
	 * @param userName
	 *            name of user
	 * @return data of Player
	 */
	public Player getPlayerInfo(String userName) {
		Player player = null;
		String sql = "select userName from user where user = '" + userName
				+ "';";
		checkDataAccess();
		try {

			mStatement.executeQuery(sql);
			ResultSet set = mStatement.getResultSet();
			player = getPlayerFromSet(set);

			mStatement.close();
			mConnect.close();

		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
		return player;
	}

	private Player getPlayerFromSet(ResultSet set) {
		Player player = new Player();
		try {
			player.mId = set.getLong("id");
			player.mUserName = set.getString("user");
			player.mName = set.getString("Name");
			player.mEmail = set.getString("email");
			player.mBirthDay = set.getLong("birthday");
			player.mGender = set.getInt("gender");
			player.mExp = set.getDouble("exp");
			player.mMoney = set.getDouble("money");
			player.mWin = set.getLong("win");
			player.mTotal = set.getLong("total");
			player.mLevel = set.getInt("level");
			player.mAvatar = set.getString("avatar");
			player.mType = set.getInt("type");
		} catch (SQLException ex) {
			ex.printStackTrace();
			return null;
		}
		return player;
	}

	/**
	 * get top users have most exp
	 * 
	 * @param size
	 * @return list {@link Player}
	 */
	public List<Player> getTop(int choice, int size) {
		if (choice != 1 && choice != 2)
			return null;
		List<Player> players = new ArrayList<Player>();
		checkDataAccess();
		try {
			if(choice==1)
			mStatement.executeQuery
			("select money from user order by money desc limit "+size);
		
			else
				mStatement.executeQuery
				("select exp from user order by exp desc limit "+size);
			ResultSet set = mStatement.getResultSet();

			if (!set.isFirst()) {
				return null;
			}
			do {
				Player player = getPlayerFromSet(set);
				if (player != null)
					players.add(player);
			} while (set.next());

			mConnect.close();
			mStatement.close();

		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}

		return players;
	}

	/**
	 * get top users have most money
	 * 
	 * @param size
	 * @return list {@link Player}
	 */

	private void checkDataAccess() {
		try {

			if (mConnect.isClosed()) {
				mConnect = DriverManager
						.getConnection(URL, USER_NAME, PASSWORD);
			}

			if (mStatement.isClosed()) {
				mStatement = mConnect.createStatement();
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
